package com.mm.fam.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mm.fam.web.base.CommonConstant;
import com.mm.fam.web.base.ResponseModel;
import com.mm.fam.web.base.ResponseUtil;
import com.mm.fam.web.entity.SysRole;
import com.mm.fam.web.entity.SysUserRole;
import com.mm.fam.web.entity.ins.SingleUserRolesBoIns;
import com.mm.fam.web.entity.ins.UserRoleAllocationBoIns;
import com.mm.fam.web.mapper.SysRoleMapper;
import com.mm.fam.web.mapper.SysUserRoleMapper;
import com.mm.fam.web.service.SysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zt
 * @since 2018-09-29
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {


    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;


    @Override
    public List<SysRole> getRoleByUserId(Integer userId) {
        return sysRoleMapper.getRoleByUserId(userId);
    }

    @Override
    public IPage<SysRole> page(int pageNum, int pageSize, String search) {
        QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
        if (StringUtils.isNoneEmpty(search)) {
            wrapper.like(true, "name", "%" + search.trim() + "%");
        }

        wrapper.orderBy(true, false, "create_time");
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        return sysRoleMapper.selectPage(page, wrapper);
    }

    @Override
    public String saveRole(SysRole role) {
        //判断是否激活
        if (null == role.getStatus()) {
            role.setStatus(0);
        }

        Date date = new Date();
        if (role.getId() != null) {
            //判断角色名称和code是角色代码是否一致，如果一致则保存成功，如果不一致
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", role.getCode());
            map.put("name", role.getName());
            int index = sysRoleMapper.queryRpleInfoByMap(map);

            role.setUpdateTime(date);
            if (index > 0) {
                updateById(role);
                return "操作成功";
            } else {
                Map<String, Object> mapCount = sysRoleMapper.findMapCountByMap(map);
                int codeCount = Integer.parseInt(mapCount.get("codeCount").toString());
                int nameCount = Integer.parseInt(mapCount.get("nameCount").toString());
                if (codeCount == 1 && nameCount == 0) {
                    updateById(role);
                    return "操作成功";
                } else if (nameCount == 1 && codeCount == 0) {
                    updateById(role);
                    return "操作成功";
                } else {
                    throw new RuntimeException(CommonConstant.Message.ROLE_CODENAME_EXIST);
                }
            }
        } else if (!queryRoleCodeNameExist(role.getCode(), role.getName())) {
            //判断角色代码和名称是否已经存在
            throw new RuntimeException(CommonConstant.Message.ROLE_CODENAME_EXIST);

        } else {
            role.setCreateTime(date);
            role.setUpdateTime(date);
            save(role);
            return "操作成功";
        }
    }

    /**
     * 新建或编辑角色时查询角色代码或名称已存在
     *
     * @param code,name,id
     * @return boolean
     */
    @Override
    public boolean queryRoleCodeNameExist(String code, String name) {

        int count = 0;
        count = sysRoleMapper.queryRoleCodeNameExist(code, name);

        if (count > 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 分页查询所有用户已分配角色
     *
     * @param pageNum
     * @param pageSize
     * @param search   支持用户名模糊查询,可传null
     * @param order    支持排序,可传null
     * @return UserRoleAllocationBo （可根据需要复写toString方法）
     */
    @Override
    public Page<UserRoleAllocationBoIns> queryUserRoleByPage(String search, Integer pageNum, Integer pageSize,
                                                             String order) {

        if (StringUtils.isBlank(search)) {
            search = null;
        } else {
            search = "%" + search.trim() + "%";
        }
        if (StringUtils.isBlank(order)) {
            order = null;
        }
        Page<UserRoleAllocationBoIns> page = new Page(pageNum, pageSize);
        List<UserRoleAllocationBoIns> list = this.sysRoleMapper.queryAllUserRolePage(page, search, order);
        page.setRecords(list);
        return page;
    }

    /**
     * 根据用户ID查询所有角色的分配情况
     *
     * @param userId
     * @return SingleUserRoleAllocationBo
     */
    @Override
    public List<SingleUserRolesBoIns> queryRoleAllocationByUserId(Integer userId) {
        List<SingleUserRolesBoIns> singleUserRolesBos = sysRoleMapper.queryRoleAllocationByUserId(userId);
        return singleUserRolesBos;
    }

    /**
     * 更新用户角色关系
     *
     * @param userId
     * @param roleIds
     * @return
     */
    @Override
    public void updateUserRoles(Integer userId, List<Integer> roleIds) throws RuntimeException {

        try {
            List<SysUserRole> sysUserRolesList = new ArrayList<SysUserRole>();
            SysUserRole sysUserRole = new SysUserRole();
            deleteAllRoleByUserId(userId);
            for (int i = 0; i < roleIds.size(); i++) {
                sysUserRole.setUserId(userId);
                Integer a = roleIds.get(i);
                sysUserRole.setRoleId(a);
                if (!sysUserRolesList.contains(sysUserRole)) {
                    sysUserRolesList.add(sysUserRole);
                }

                sysUserRoleMapper.batchInsertUserRoles(sysUserRolesList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("更新用户角色失败");
        }

        /*
         * 用户角色变更后 此处应考虑添加清空当前缓存的用户角色信息
         * 使用realm中的clearCachedAuthorizationInfo()方法
         */
    }

    /**
     * 插入单个角色
     *
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    public void updateUserRole(Integer userId, Integer roleId) throws RuntimeException {

        // 用户角色关系是否存在标志
        boolean existFlag = false;
        List<SingleUserRolesBoIns> singleUserRolesBos = new ArrayList<SingleUserRolesBoIns>();
        singleUserRolesBos = queryRoleAllocationByUserId(userId);
        Iterator<SingleUserRolesBoIns> iterator = singleUserRolesBos.iterator();
        while (iterator.hasNext()) {
            SingleUserRolesBoIns singleUserRolesBoIns = iterator.next();
            if (singleUserRolesBoIns.getRoleId() == roleId) {
                existFlag = true;
                break;
            }
        }
        if (!existFlag) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            try {
                sysUserRoleMapper.insert(sysUserRole);
            } catch (Exception e) {
                throw new RuntimeException("更新用户角色失败");
            }
        }

    }

    /**
     * 查询单个用户角色是否存在
     *
     * @param userId
     * @param roleId
     * @return boolean
     */
    @Override
    public boolean queryExistUserRole(String userId, String roleId) {
        /*
         * 代码未实现
         */
        return true;
    }

    /**
     * 根据用户ID删除所有已分配角色
     *
     * @param userId
     * @return
     */
    @Override
    public void deleteAllRoleByUserId(Integer userId) throws RuntimeException {
        sysRoleMapper.deleteAllRoleByUserId(userId);
    }

    /**
     * 用户角色分配页面，查询  翻页总数据量
     *
     * @return int
     */
    @Override
    public int queryNumOfUser() {
        return sysRoleMapper.queryNumOfUser();
    }

    /**
     * 删除角色前查询角色下是否已分配权限
     *
     * @param roleId
     * @return int
     */
    @Override
    public int queryPerAllocationNumOfRole(Integer roleId) {
        return sysRoleMapper.queryPerAllocationNumOfRole(roleId);
    }

    @Override
    public int queryRoleByUserCount(Integer roleId) {
        return sysRoleMapper.queryRoleByUserCount(roleId);
    }

    @Override
    public ResponseEntity<ResponseModel<List<SysRole>>> queryRoleListNoPage() {
        ResponseEntity<ResponseModel<List<SysRole>>> re= null;
        List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("status", 1));
        re = ResponseUtil.success(sysRoles);
        return re;
    }


    @Override
    public List<String> getRoleStrByUserId(Integer userId) {
        List<SysRole> roles = sysRoleMapper.getRoleByUserId(userId);
        List<String> userRole = new ArrayList<String>();
        for (SysRole sr : roles) {
            userRole.add(sr.getCode());
        }
        return userRole;
    }
}
